package com.example.d8_stream;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Stream流终结方法
 */
/*
void forEach(Consumer action)                             对此流运算后的元素执行遍历
long count()                                              统计此流运算后的元素个数
Optional <T>max(Comparator<?super T>comparator)           获取此流运算后的最大值元素
Optional <T>min(Comparator<?super T>comparator)           获取此流运算后的最小值元素
 */
public class StreamTest4 {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        Student s1 = new Student("蜘蛛精", 26, 172.5);
        Student s2 = new Student("蜘蛛精", 26, 172.5);
        Student s3 = new Student("紫霞", 23, 167.6);
        Student s4 = new Student("白晶晶", 25, 169.0);
        Student s5 = new Student("牛魔王", 35, 183.3);
        Student s6 = new Student("牛夫人", 34, 168.5);
        Collections.addAll(students, s1, s2, s3, s4, s5, s6);
        // 需求1：请计算出身高超过168的学生有几人
        long size = students.stream().filter(s -> s.getHeight() > 168).count();
        System.out.println(size);

        // 需求2：请找出身高最高的学生对象,并输出
        // 原始的写法
//        Student s = students.stream().max(new Comparator<Student>() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                return Double.compare(o1.getHeight(), o2.getHeight());
//            }
//        }).get();
        // Lambda表达式的写法
        Student s = students.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
        System.out.println(s);


        // 需求3：请找出身高最矮的学生对象,并输出
        Student ss = students.stream().min(((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()))).get();
        System.out.println(ss);


        /**
         * 收集stream流
         * R collect(Collector collector) 把stream流处理好的数据收集到集合中
         * Object[] toArray() 把stream流中的元素收集到数组中
         */
        // 需求4：请找出身高超过170的学生对象,并放到一个新集合中去返回
        // 注意流只能收集一次
        List<Student> students1 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toList());
        System.out.println(students1);

        // 把收集到的数据放到set集合中 那么最后调的方法就是Collectors.toSet()
        Set<Student> students2 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toSet());
        System.out.println(students2);


        // 需求5：请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Map集合返回
        // 注意在把过滤之后的数据放到map集合中,那么最后调的方法就是Collectors.toMap()
        Map<String, Double> map =
                students.stream().filter(a -> a.getHeight() > 170)
                        .distinct() // map集合不能去重 所有需要自己手动的去重复
                        // 但是不能直接放到Map中因为 他不知道你需要存入什么所有需要自己指定键和值
                        // 这里表示用名字作为键 升高作为值
                        .collect(Collectors.toMap(Student::getName, Student::getHeight));
        System.out.println(map);

        // 把流收集到数组中
        // Object[] arr = students.stream().filter(a -> a.getHeight() > 170).toArray();
        // 如果要把stream流收集到的数据存放到Student数组中 那么最后调的方法就是Collectors.toArray(里面加上 len-> new Student[len])
        // Student[] arr = students.stream().filter(a -> a.getHeight() > 170).toArray(len -> new Student[len]);
        // 使用方法引用简化
        Student[] arr = students.stream().filter(a -> a.getHeight() > 170).toArray(Student[]::new);

        System.out.println(Arrays.toString(arr));
    }
}

